import os
import re
import logging

from agent.feature.base import Feature
from agent.common.system import sysCommand
from agent.common.config import Config

logger = logging.getLogger("common")

class SchedFeature(Feature):
    __domain__  = "kernel_cpu"
    __feature__ = "sched_features"
    
    def __init__(self):
        super().__init__(self.__domain__, self.__feature__)
        self.shced_features_config = "/sys/kernel/debug/sched_features"
        assert os.path.exists(self.shced_features_config)
        self.backup_file = os.path.join(
            Config.BACKUP_PATH, "{}_{}.json".format(self.__domain__, self.__feature__))
    
    def reverse_param(self, param):
        if param.startswith("NO"):
            return param[3:]
        else:
            return "NO_" + param
    
    def get_value(self):
        return ""
    
    def set_value(self, value):
        if value == "":
            return
        
        backup_param = []
        for v in re.split(r"[\s,;]*", value):
        # for v in value.split(','):
            try:
                sysCommand("echo {} > {}".format(v, self.shced_features_config), log = True)
            except Exception:
                raise
            else:
                backup_param.append(v)
        
        logger.info("backup appended param: {}".format(backup_param))
        with open(self.backup_file, "w") as f:
            f.write(",".join(backup_param))

    def backup(self):
        return ""
    
    def rollback(self):
        if not os.path.exists(self.backup_file):
            return
        
        with open(self.backup_file) as f:
            backup_param = f.read()
            for v in backup_param.split(','):
                reversed_value = self.reverse_param(v)
                try:
                    sysCommand("echo {} > {}".format(reversed_value, self.shced_features_config), log = True)
                except Exception:
                    raise
        
        
if __name__ == "__main__":
    handler = SchedFeature()
    handler.backup()
    handler.set_value("PREFER_TTWU_QUEUE NO_WAKEUP_PREEMPTION")
    handler.rollback()
